//! 事件模块
//! 
//! 定义市场事件和事件处理功能

use std::collections::HashMap;
use serde::{Deserialize, Serialize};
use chrono::{DateTime, Utc};
use crate::objects::bar::RawBar;

/// 事件类型枚举
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
pub enum EventType {
    /// 价格突破
    PriceBreak,
    /// 成交量异常
    VolumeAnomaly,
    /// 技术指标信号
    TechnicalSignal,
    /// 基本面事件
    FundamentalEvent,
    /// 市场情绪
    MarketSentiment,
    /// 其他事件
    Other,
}

/// 事件级别枚举
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
pub enum EventLevel {
    /// 低级别
    Low,
    /// 中级别
    Medium,
    /// 高级别
    High,
    /// 紧急
    Critical,
}

/// 事件结构体
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Event {
    /// 事件ID
    pub id: String,
    /// 事件类型
    pub event_type: EventType,
    /// 事件级别
    pub level: EventLevel,
    /// 事件时间
    pub dt: DateTime<Utc>,
    /// 事件描述
    pub description: String,
    /// 事件数据
    pub data: HashMap<String, serde_json::Value>,
    /// 相关标的
    pub symbol: String,
    /// 是否已处理
    pub processed: bool,
    /// 创建时间
    pub created_at: DateTime<Utc>,
}

impl Event {
    /// 创建新事件
    pub fn new(
        id: String,
        event_type: EventType,
        level: EventLevel,
        dt: DateTime<Utc>,
        description: String,
        symbol: String,
    ) -> Self {
        Self {
            id,
            event_type,
            level,
            dt,
            description,
            data: HashMap::new(),
            symbol,
            processed: false,
            created_at: Utc::now(),
        }
    }
    
    /// 添加事件数据
    pub fn add_data(&mut self, key: String, value: serde_json::Value) {
        self.data.insert(key, value);
    }
    
    /// 标记为已处理
    pub fn mark_processed(&mut self) {
        self.processed = true;
    }
    
    /// 获取事件摘要
    pub fn get_summary(&self) -> String {
        format!(
            "[{}] {} - {} - {}",
            self.level.as_str(),
            self.event_type.as_str(),
            self.symbol,
            self.description
        )
    }
    
    /// 检查是否为紧急事件
    pub fn is_critical(&self) -> bool {
        self.level == EventLevel::Critical
    }
    
    /// 检查是否为高级别事件
    pub fn is_high_priority(&self) -> bool {
        matches!(self.level, EventLevel::High | EventLevel::Critical)
    }
}

impl EventType {
    /// 获取事件类型字符串表示
    pub fn as_str(&self) -> &'static str {
        match self {
            EventType::PriceBreak => "价格突破",
            EventType::VolumeAnomaly => "成交量异常",
            EventType::TechnicalSignal => "技术指标信号",
            EventType::FundamentalEvent => "基本面事件",
            EventType::MarketSentiment => "市场情绪",
            EventType::Other => "其他事件",
        }
    }
}

impl EventLevel {
    /// 获取事件级别字符串表示
    pub fn as_str(&self) -> &'static str {
        match self {
            EventLevel::Low => "低",
            EventLevel::Medium => "中",
            EventLevel::High => "高",
            EventLevel::Critical => "紧急",
        }
    }
}

/// 事件处理器特征
pub trait EventHandler {
    /// 处理事件
    fn handle_event(&mut self, event: &Event) -> Result<(), String>;
    
    /// 检查是否支持该事件类型
    fn supports_event_type(&self, event_type: EventType) -> bool;
    
    /// 获取处理器名称
    fn get_name(&self) -> &str;
}

/// 事件管理器
pub struct EventManager {
    /// 事件处理器列表
    handlers: Vec<Box<dyn EventHandler>>,
    /// 事件历史
    events: Vec<Event>,
    /// 配置
    config: HashMap<String, serde_json::Value>,
}

impl EventManager {
    /// 创建新的事件管理器
    pub fn new(config: HashMap<String, serde_json::Value>) -> Self {
        Self {
            handlers: Vec::new(),
            events: Vec::new(),
            config,
        }
    }
    
    /// 添加事件处理器
    pub fn add_handler(&mut self, handler: Box<dyn EventHandler>) {
        self.handlers.push(handler);
    }
    
    /// 发布事件
    pub fn publish_event(&mut self, event: Event) -> Result<(), String> {
        // 添加到事件历史
        self.events.push(event.clone());
        
        // 通知所有处理器
        for handler in &mut self.handlers {
            if handler.supports_event_type(event.event_type) {
                if let Err(e) = handler.handle_event(&event) {
                    return Err(format!("处理器 {} 处理事件失败: {}", handler.get_name(), e));
                }
            }
        }
        
        Ok(())
    }
    
    /// 获取事件历史
    pub fn get_events(&self) -> &[Event] {
        &self.events
    }
    
    /// 获取未处理的事件
    pub fn get_unprocessed_events(&self) -> Vec<&Event> {
        self.events.iter().filter(|e| !e.processed).collect()
    }
    
    /// 获取高级别事件
    pub fn get_high_priority_events(&self) -> Vec<&Event> {
        self.events.iter().filter(|e| e.is_high_priority()).collect()
    }
    
    /// 清理旧事件
    pub fn cleanup_old_events(&mut self, days: i64) {
        let cutoff = Utc::now() - chrono::Duration::days(days);
        self.events.retain(|e| e.created_at > cutoff);
    }
}

/// 价格突破事件检测器
pub struct PriceBreakDetector {
    /// 突破阈值
    threshold: f64,
    /// 检测周期
    period: usize,
}

impl PriceBreakDetector {
    /// 创建新的价格突破检测器
    pub fn new(threshold: f64, period: usize) -> Self {
        Self {
            threshold,
            period,
        }
    }
    
    /// 检测价格突破
    pub fn detect_break(&self, bars: &[RawBar]) -> Option<Event> {
        if bars.len() < self.period {
            return None;
        }
        
        let current_bar = &bars[bars.len() - 1];
        let previous_bars = &bars[bars.len() - self.period..bars.len() - 1];
        
        // 计算前期平均价格
        let avg_price: f64 = previous_bars.iter().map(|b| b.close).sum::<f64>() / previous_bars.len() as f64;
        
        // 检查是否突破
        let price_change = (current_bar.close - avg_price) / avg_price;
        
        if price_change.abs() > self.threshold {
            let event_type = if price_change > 0.0 {
                EventType::PriceBreak
            } else {
                EventType::PriceBreak
            };
            
            let level = if price_change.abs() > self.threshold * 2.0 {
                EventLevel::Critical
            } else if price_change.abs() > self.threshold * 1.5 {
                EventLevel::High
            } else {
                EventLevel::Medium
            };
            
            let description = format!(
                "价格突破: 当前价格 {:.2}, 平均价格 {:.2}, 变化率 {:.2}%",
                current_bar.close, avg_price, price_change * 100.0
            );
            
            let mut event = Event::new(
                format!("price_break_{}", current_bar.dt.timestamp()),
                event_type,
                level,
                current_bar.dt,
                description,
                current_bar.symbol.clone(),
            );
            
            event.add_data("price_change".to_string(), serde_json::Value::Number(serde_json::Number::from_f64(price_change).unwrap()));
            event.add_data("threshold".to_string(), serde_json::Value::Number(serde_json::Number::from_f64(self.threshold).unwrap()));
            
            Some(event)
        } else {
            None
        }
    }
}

impl EventHandler for PriceBreakDetector {
    fn handle_event(&mut self, event: &Event) -> Result<(), String> {
        // 价格突破事件处理逻辑
        println!("处理价格突破事件: {}", event.get_summary());
        Ok(())
    }
    
    fn supports_event_type(&self, event_type: EventType) -> bool {
        event_type == EventType::PriceBreak
    }
    
    fn get_name(&self) -> &str {
        "PriceBreakDetector"
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    
    #[test]
    fn test_event_creation() {
        let event = Event::new(
            "test_1".to_string(),
            EventType::PriceBreak,
            EventLevel::High,
            Utc::now(),
            "测试事件".to_string(),
            "000001.SZ".to_string(),
        );
        
        assert_eq!(event.id, "test_1");
        assert_eq!(event.event_type, EventType::PriceBreak);
        assert_eq!(event.level, EventLevel::High);
        assert!(!event.processed);
    }
    
    #[test]
    fn test_event_summary() {
        let event = Event::new(
            "test_2".to_string(),
            EventType::VolumeAnomaly,
            EventLevel::Critical,
            Utc::now(),
            "成交量异常".to_string(),
            "000001.SZ".to_string(),
        );
        
        let summary = event.get_summary();
        assert!(summary.contains("紧急"));
        assert!(summary.contains("成交量异常"));
        assert!(summary.contains("000001.SZ"));
    }
    
    #[test]
    fn test_event_manager() {
        let mut manager = EventManager::new(HashMap::new());
        
        let event = Event::new(
            "test_3".to_string(),
            EventType::TechnicalSignal,
            EventLevel::Medium,
            Utc::now(),
            "技术信号".to_string(),
            "000001.SZ".to_string(),
        );
        
        assert!(manager.publish_event(event).is_ok());
        assert_eq!(manager.get_events().len(), 1);
    }
    
    #[test]
    fn test_price_break_detector() {
        let detector = PriceBreakDetector::new(0.05, 5);
        
        // 创建测试K线数据
        let mut bars = Vec::new();
        for i in 0..10 {
            let bar = RawBar {
                symbol: "000001.SZ".to_string(),
                dt: Utc::now() + chrono::Duration::days(i),
                open: 10.0,
                close: if i < 5 { 10.0 } else { 11.0 }, // 最后5根K线价格上涨
                high: 11.0,
                low: 9.0,
                volume: 1000.0,
                amount: 10000.0,
                cache: None,
            };
            bars.push(bar);
        }
        
        let event = detector.detect_break(&bars);
        assert!(event.is_some());
        
        if let Some(event) = event {
            assert_eq!(event.event_type, EventType::PriceBreak);
            assert!(event.is_high_priority());
        }
    }
} 